package org.octopus.data.desensitized.jackson.util;

import com.fasterxml.jackson.databind.BeanProperty;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import lombok.extern.slf4j.Slf4j;
import org.octopus.data.desensitized.core.annotation.Desensitized;
import org.octopus.data.desensitized.core.annotation.DesensitizedRule;
import org.octopus.data.desensitized.core.util.DesensitizedUtils;
import org.octopus.data.desensitized.jackson.annotation.JacksonDesensitized;

/**
 * 数据脱敏工具类
 */
@Slf4j
public class JacksonDesensitizedUtils {

    public static DesensitizedRule obtainDesensitizedRule(Field field) {
        JacksonDesensitized jacksonDesensitized = field.getAnnotation(JacksonDesensitized.class);

        if (jacksonDesensitized != null) {
            return JacksonDesensitizedUtils.buildDesensitizedRule(jacksonDesensitized);
        }

        return null;
    }

    public static DesensitizedRule obtainDesensitizedRule(BeanProperty property) {
        JacksonDesensitized jacksonDesensitized =
                JacksonDesensitizedUtils.obtainDesensitizedRule(property, JacksonDesensitized.class);

        if (jacksonDesensitized != null) {
            return JacksonDesensitizedUtils.buildDesensitizedRule(jacksonDesensitized);
        }

        Desensitized desensitized = property.getAnnotation(Desensitized.class);

        if (desensitized != null) {
            return DesensitizedUtils.buildDesensitizedRule(desensitized);
        }

        return null;
    }

    public static <A extends Annotation> A obtainDesensitizedRule(BeanProperty property, Class<A> annotation) {
        A desensitized = property.getAnnotation(annotation);

        if (desensitized == null) {
            if (log.isDebugEnabled()) {
                log.debug("字段[{}]上脱敏注解[{}]未找到", property.getName(), annotation);
            }

            desensitized = property.getContextAnnotation(annotation);
        }

        return desensitized;
    }

    /**
     * @param desensitized
     * @return
     */
    public static DesensitizedRule buildDesensitizedRule(JacksonDesensitized desensitized) {
        return DesensitizedRule.builder()
                .desensitizedType(desensitized.desensitizedType())
                .desensitizedPolicy(desensitized.desensitizedPolicy())
                .enable(desensitized.enable())
                .replacePrefixIgnoreLength(desensitized.replacePrefixIgnoreLength())
                .replaceSuffixIgnoreLength(desensitized.replaceSuffixIgnoreLength())
                .replaceMaskSymbol(desensitized.replaceMaskSymbol())
                .replaceOverallValue(desensitized.replaceOverallValue())
                .appendStartIndex(desensitized.appendStartIndex())
                .appendMaskSymbol(desensitized.appendMaskSymbol())
                .appendMaskSymbolNumber(desensitized.appendMaskSymbolNumber())
                .appendSpecialValue(desensitized.appendSpecialValue())
                .cutStartIndex(desensitized.cutStartIndex())
                .cutLength(desensitized.cutLength())
                .build();
    }
}